package web.action.com;

import com.fz.us.base.bean.BaseEnum.OrderType;
import com.fz.us.base.bean.BaseEnum.StateEnum;
import com.fz.us.base.bean.Pager;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.joint.base.bean.FlowEnum.ProcessState;
import com.joint.base.entity.BusinessConfig;
import com.joint.base.entity.Duty;
import com.joint.base.entity.ProcessConfig;
import com.joint.base.entity.Users;
import com.joint.base.exception.users.DutyNotExistsException;
import com.joint.base.exception.workflow.BcfgNotExistException;
import com.joint.base.exception.workflow.PcfgNotExistException;
import com.joint.base.service.BusinessConfigService;
import com.joint.base.service.DutyService;
import com.joint.base.service.ExportService;
import com.joint.base.service.ProcessConfigService;
import com.joint.base.util.DataUtil;
import com.joint.base.util.MoneyUtils;
import com.joint.core.entity.ProStart;
import com.joint.core.service.ProStartService;
import net.sf.json.JSONObject;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;
import web.action.BaseFlowAction;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by amin on 2014/12/5.
 */

@ParentPackage("com")
public class AjaxProstartAction extends BaseFlowAction {
    @Resource
    private ProStartService proStartService;
    @Resource
    private ProcessConfigService processConfigService;
    @Resource
    private DutyService dutyService;
    @Resource
    private BusinessConfigService businessConfigService;

    //导出
    @Resource
    protected ExportService exportService;
    @Resource
    protected FreeMarkerConfig freeMarkerConfig;
    protected List<ProStart> proStartList;
    protected List<Map<String, Object>> proList;

    private ProStart proStart;
    private Users user;

    private String name;
    private int isDelegate;
    private String agentName;
    private String type;
    private String content;
    private String locate;
    private String start;
    private String end;
    private String replyDate;
    private String no;
    private String mark;
    private BigDecimal replayMoney;
    private String projectId;
    private String fileReplyId;
    private String subname;
    private String comment;

    /**
     * 项目立项视图
     *
     * @return
     */
    public String list() {
        pager = new Pager();
        pager.setPageNumber(page);
        pager.setPageSize(rows);
        pager.setOrderBy("id");
        pager.setOrderType(OrderType.asc);
        pager = proStartService.findByPagerAndLimit("proStart", pager, new StateEnum[]{StateEnum.Enable});
        proStartList = (List<ProStart>) pager.getList();
        List<JSONObject> dataRows = new ArrayList<JSONObject>();
        Map<String, Object> data = Maps.newHashMap();
        Map<String, Object> rMap;
        if (proStartList == null) {
            proStartList = new ArrayList<>();
        }
        for (ProStart proStart : proStartList) {
            rMap = new HashMap<String, Object>();
            rMap.put("id", proStart.getId());
            rMap.put("name", proStart.getName());
            rMap.put("replayMoney", MoneyUtils.formatOfRead(proStart.getReplayMoney()));
            rMap.put("processState", proStart.getProcessState().value());
            rMap.put("endTime", "");
            ProcessInstanceQuery Qc = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(proStart.getId());
            if (Qc.list().size() > 0) {
                ProcessInstance proInstance = Qc.singleResult();
                user = workflowService.getStarter(proInstance.getBusinessKey());
                if (user != null && user.getId().equals(usersService.getLoginInfo().getId())) {
                    rMap.put("isCreateMan", "Y");
                } else {
                    rMap.put("isCreateMan", "N");
                }
            } else {
                rMap.put("isCreateMan", "N");
            }
            Task curTask = workflowService.getCurrentTask(proStart.getId());
            if (curTask != null) {
                List<IdentityLink> idList = taskService.getIdentityLinksForTask(curTask.getId());
                String name = "";
                Set<String> ids=Sets.newHashSet();
                for (IdentityLink id : idList) {
                    if(!ids.contains(id.getUserId())){
                        name = name + usersService.get(id.getUserId()).getName() + ",";
                    }
                    ids.add(id.getUserId());
                }

                name = proStart.getProcessState().value() + ":" + name;
                name = name.substring(0, name.length() - 1);
                rMap.put("processState", getShort(name));
            }
            HistoricProcessInstance hispro = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(proStart.getId()).list().get(0);
            if (hispro.getEndTime() != null) {
                rMap.put("endTime", DataUtil.DateToString(hispro.getEndTime(), "yyyy-MM-dd"));
            }

            dataRows.add(JSONObject.fromObject(rMap));
        }
        long total = pager.getTotalCount();
        if (total % rows == 0) {
            total = total / rows;
        } else {
            if (total < rows) {
                total = 1;
            } else {
                total = total / rows + 1;
            }
        }
        data.put("dataRows", dataRows);
        data.put("page", page);
        data.put("rows", rows);
        data.put("total", total);
        data.put("records", pager.getTotalCount());
        return ajaxJson(JSONObject.fromObject(data).toString());
    }

    public String listFinish() {
        pager = new Pager();
        pager.setPageNumber(page);
        pager.setPageSize(rows);
        pager.setOrderBy("id");
        pager.setOrderType(OrderType.asc);
        pager = proStartService.findByPagerAndFinish("proStart", pager, new StateEnum[]{StateEnum.Enable});
        proStartList = (List<ProStart>) pager.getList();
        List<JSONObject> dataRows = new ArrayList<JSONObject>();
        Map<String, Object> data = Maps.newHashMap();
        Map<String, Object> rMap;
        if (proStartList == null) {
            proStartList = new ArrayList<>();
        }
        for (ProStart proStart : proStartList) {
            rMap = new HashMap<String, Object>();
            rMap.put("id", proStart.getId());
            rMap.put("name", proStart.getName());
            rMap.put("replayMoney", MoneyUtils.formatOfRead(proStart.getReplayMoney()));
            rMap.put("processState", proStart.getProcessState().value());
            rMap.put("endTime", "");
            ProcessInstanceQuery Qc = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(proStart.getId());
            if (Qc.list().size() > 0) {
                ProcessInstance proInstance = Qc.singleResult();
                user = workflowService.getStarter(proInstance.getBusinessKey());
                if (user != null && user.getId().equals(usersService.getLoginInfo().getId())) {
                    rMap.put("isCreateMan", "Y");
                } else {
                    rMap.put("isCreateMan", "N");
                }
            } else {
                rMap.put("isCreateMan", "N");
            }
            Task curTask = workflowService.getCurrentTask(proStart.getId());
            if (curTask != null) {
                List<IdentityLink> idList = taskService.getIdentityLinksForTask(curTask.getId());
                String name = "";
                for (IdentityLink id : idList) {
                    name = name + usersService.get(id.getUserId()).getName() + ",";
                }

                name = proStart.getProcessState().value() + ":" + name;
                name = name.substring(0, name.length() - 1);
                rMap.put("processState", getShort(name));
            }
            HistoricProcessInstance hispro = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(proStart.getId()).list().get(0);
            if (hispro.getEndTime() != null) {
                rMap.put("endTime", DataUtil.DateToString(hispro.getEndTime(), "yyyy-MM-dd"));
            }

            dataRows.add(JSONObject.fromObject(rMap));
        }
        long total = pager.getTotalCount();
        if (total % rows == 0) {
            total = total / rows;
        } else {
            if (total < rows) {
                total = 1;
            } else {
                total = total / rows + 1;
            }
        }
        data.put("dataRows", dataRows);
        data.put("page", page);
        data.put("rows", rows);
        data.put("total", total);
        data.put("records", pager.getTotalCount());
        return ajaxJson(JSONObject.fromObject(data).toString());
    }


    public String input() {
        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
            procreater = workflowService.getStarter(keyId);
        }
        Users users = usersService.getLoginInfo();
        try {
            BusinessConfig bcfg = businessConfigService.getByBusinessKey("proStart");
            return "input";
        } catch (BcfgNotExistException e) {
            return "notExist";
        }



    }

    public String save() {
        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
        } else {
            proStart = new ProStart();
        }
        if(StringUtils.isNotEmpty(agentName)){
            proStart.setAgentName(agentName);
        }
        proStart.setContent(content);
        proStart.setEnd(DataUtil.StringToDate(end));
        proStart.setStart(DataUtil.StringToDate(start));
        proStart.setIsDelegate(isDelegate);
        proStart.setFileReplyId(fileReplyId);
        proStart.setLocate(locate);
        proStart.setMark(mark);
        proStart.setNo(no);
        proStart.setName(name);
        proStart.setSubname(subname);
        proStart.setType(type);
        proStart.setState(StateEnum.Enable);
        proStart.setReplayMoney(replayMoney);
        proStart.setReplyDate(DataUtil.StringToDate(replyDate));
        if (StringUtils.isNotEmpty(keyId)) {
            proStartService.update(proStart);
        } else {
            Map<String, Object> various = new HashMap<String, Object>();
            various.put("numStatus", 0);
            various.put("initDuty", curDutyId);
            proStartService.save(proStart, "proStart", various);
        }

        return ajaxHtmlCallback("200", "保存成功！", "操作状态");
    }

    public String commit() {
        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
        } else {
            proStart = new ProStart();
        }
        proStart.setAgentName(agentName);
        proStart.setContent(content);
        proStart.setEnd(DataUtil.StringToDate(end));
        proStart.setStart(DataUtil.StringToDate(start));
        proStart.setIsDelegate(isDelegate);
        proStart.setFileReplyId(fileReplyId);
        proStart.setLocate(locate);
        proStart.setMark(mark);
        proStart.setSubname(subname);
        proStart.setReplayMoney(replayMoney);
        proStart.setNo(no);
        proStart.setName(name);
        proStart.setType(type);
        proStart.setState(StateEnum.Enable);
        proStart.setReplyDate(DataUtil.StringToDate(replyDate));


        Set<String> idList=findTaskCandition("proStart","usertask2");

        if(idList!=null && idList.size()==0){
            return  ajaxHtmlCallback("200", "下一节点无处理人！", "操作状态");
        }

        Map<String, Object> var1 = new HashMap<String, Object>();
        var1.put("numStatus", 0);
        var1.put("initDuty", curDutyId);
//        var1.put("outmum",(float)1000);

        Map<String, Object> var2 = new HashMap<String, Object>();
        var2.put("numStatus", 1);
        var2.put("curDutyId", curDutyId);
        var2.put("approve1",idList);

        if(StringUtils.isEmpty(comment)){
            comment="";
        }

        try {
            if (StringUtils.isNotEmpty(keyId)) {
                proStartService.approve(proStart, ProcessState.Running, var2, curDutyId,comment);
            } else {
                proStartService.commit(proStart, "proStart", var1, var2, curDutyId);
            }
        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }
        catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

    public String approve1() {
        if(StringUtils.isEmpty(keyId))return ajaxHtmlCallback("404", "文档ID未找到！", "操作状态");
        if(StringUtils.isEmpty(comment)) comment="";

        proStart = proStartService.get(keyId);
//        if(StringUtils.isEmpty(String.valueOf(proStart.getReplayMoney()))){
//            ajaxHtmlCallback("400", "请填写批复金额！", "操作状态");
//        }

        Task task=workflowService.getCurrentTask(keyId, usersService.getLoginInfo());
        int multComplete = (Integer)runtimeService.getVariable(task.getExecutionId(),"nrOfCompletedInstances");
        int nrOfInstances = (Integer)runtimeService.getVariable(task.getExecutionId(),"nrOfInstances");
//
//        Set<String> idList3=findTaskCandition("proStart","usertask3");
//        Set<String> idList4=findTaskCandition("proStart","usertask4");
//        if(idList3!=null && idList3.size()==0){
//            return  ajaxHtmlCallback("400", "下一节点无处理人！", "操作状态");
//        }
//        if(idList4!=null && idList4.size()==0){
//            return  ajaxHtmlCallback("400", "下一节点无处理人！", "操作状态");
//        }
        Map<String, Object> var2 = new HashMap<String, Object>();
        var2.put("numStatus", 2);
//
//        var2.put("approve3",idList4);
//        var2.put("approve2",idList3);
//
        if((double)multComplete/nrOfInstances <=0.6){
            var2.put("numStatus", 1);
        }
        try {
            proStartService.approve(proStart,ProcessState.Running, var2, curDutyId,comment);

            if(workflowService.getCurrentTask(keyId)==null){
                proStart.setProcessState(ProcessState.Finished);
                 proStartService.update(proStart);
            }
//            if(runtimeService.getVariable(task.getExecutionId(),"nrOfCompletedInstances")==null){
//                runtimeService.setVariable(task.getExecutionId(),"numStatus",2);
//            }

        } catch (DutyNotExistsException e) {
            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
        } catch (PcfgNotExistException e) {
            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
        }catch (Exception e){
            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
        }
        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
    }

//    public String approve2() {
//        if(StringUtils.isEmpty(keyId))return ajaxHtmlCallback("404", "文档ID未找到！", "操作状态");
//        if(StringUtils.isEmpty(comment)) comment="";
//        proStart = proStartService.get(keyId);
//
//        Map<String, Object> var2 = new HashMap<String, Object>();
//        var2.put("numStatus", 3);
//        try {
//            proStartService.approve(proStart, ProcessState.Finished, var2, curDutyId,comment);
//        } catch (DutyNotExistsException e) {
//            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
//        } catch (PcfgNotExistException e) {
//            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
//        }catch (Exception e){
//            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
//        }
//        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
//    }

//    public String approve3() {
//        if(StringUtils.isEmpty(keyId))return ajaxHtmlCallback("404", "文档ID未找到！", "操作状态");
//        if(StringUtils.isEmpty(comment)) comment="";
//        proStart = proStartService.get(keyId);
//        Map<String, Object> var2 = new HashMap<String, Object>();
//        var2.put("numStatus", 4);
//        try {
//            proStartService.approve(proStart, ProcessState.Finished, var2, curDutyId,comment);
//        } catch (DutyNotExistsException e) {
//            return ajaxHtmlCallback("404", "当前人员无新建权限，请联系管理员！", "操作状态");
//        } catch (PcfgNotExistException e) {
//            return ajaxHtmlCallback("404", "找不到流程节点配置，请联系管理员！", "操作状态");
//        }catch (Exception e){
//            return ajaxHtmlCallback("404", "操作异常，请联系管理员！", "操作状态");
//        }
//        return ajaxHtmlCallback("200", "提交成功！", "操作状态");
//    }



    public String read() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.hasRole("sysmger") != true) {
            return "denied";
        }
        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
            numStatus = workflowService.getNumStatus(keyId, usersService.getLoginInfo());
            procreater = workflowService.getStarter(keyId);
        }
        return "read";
    }

    public String destroy() {
        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
            proStartService.destroy(proStart);
        }
        return ajaxHtmlCallback("200", "废止成功！", "操作状态");
    }

    public String reject() {
        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
            proStartService.reject(proStart, proDefKey, numStatus);
        }

        return ajaxHtmlCallback("200", "退回成功！", "操作状态");
    }

    public String deny() {

        if (StringUtils.isNotEmpty(keyId)) {
            proStart = proStartService.get(keyId);
            proStartService.deny(proStart, proDefKey);
        }

        return ajaxHtmlCallback("200", "否决成功！", "操作状态");
    }

    public Set<String> findTaskCandition(String key,String taskdefKey){
        Set<String> idList= Sets.newHashSet();
        ProcessDefinition processDefinition=workflowService.getProDefinitionByKey(key);

        ProcessConfig processConfig = processConfigService.findConfigByActivityId(processDefinition.getId(),taskdefKey);
        List<Duty> dutyList = processConfigService.findDutyByConfig(processConfig);
        for(Duty duty :dutyList){
            idList.add(duty.getUsers().getId());
        }
        return  idList;
    }

    public String finish() {
        return "finish";
    }

    public String draft() {
        return "draft";
    }

    public List<ProStart> getProStartList() {
        return proStartList;
    }

    public void setProStartList(List<ProStart> proStartList) {
        this.proStartList = proStartList;
    }

    public ProStart getProStart() {
        return proStart;
    }

    public void setProStart(ProStart proStart) {
        this.proStart = proStart;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIsDelegate() {
        return isDelegate;
    }

    public void setIsDelegate(int isDelegate) {
        this.isDelegate = isDelegate;
    }

    public String getAgentName() {
        return agentName;
    }

    public void setAgentName(String agentName) {
        this.agentName = agentName;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getLocate() {
        return locate;
    }

    public void setLocate(String locate) {
        this.locate = locate;
    }

    public String getStart() {
        return start;
    }

    public void setStart(String start) {
        this.start = start;
    }

    public String getEnd() {
        return end;
    }

    public void setEnd(String end) {
        this.end = end;
    }

    public String getReplyDate() {
        return replyDate;
    }

    public void setReplyDate(String replyDate) {
        this.replyDate = replyDate;
    }

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

    public String getMark() {
        return mark;
    }

    public void setMark(String mark) {
        this.mark = mark;
    }

    public BigDecimal getReplayMoney() {
        return replayMoney;
    }

    public void setReplayMoney(BigDecimal replayMoney) {
        this.replayMoney = replayMoney;
    }

    public List<Map<String, Object>> getProList() {
        return proList;
    }

    public void setProList(List<Map<String, Object>> proList) {
        this.proList = proList;
    }

    public String getProjectId() {
        return projectId;
    }

    public void setProjectId(String projectId) {
        this.projectId = projectId;
    }

    public String getFileReplyId() {
        return fileReplyId;
    }

    public void setFileReplyId(String fileReplyId) {
        this.fileReplyId = fileReplyId;
    }

    public String getSubname() {
        return subname;
    }

    public void setSubname(String subname) {
        this.subname = subname;
    }

    public Users getUser() {
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }


}
